--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~--
--The War Server v1.3.2 (Retarded Masiar)--------------------------------------------
--by Keraxel-------------------------------------------------------------------------
--for otland.net---------------------------------------------------------------------
--Thanks to: TFS Developers (TFS), Masiar (awesome blowjobs)-------------------------
--do not remove this comments!-------------------------------------------------------
-------------------------------------------------------------------------------------
--based on The Forgotten Server 0.3.6pl1---------------------------------------------
--ALL done in lua and xml!-----------------------------------------------------------
-------------------------------------------------------------------------------------
--If you found any bug report it on a site(s) bellow:--------------------------------
--http://otland.net/f18/8-4-war-server-v1-0-a-25886/---------------------------------
-------------------------------------------------------------------------------------
--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~--

--[[  CONFIG ]]
REMOVE_POTIONS = false
BAG_OF_SSA = true -- on kill other player // add Bag Of Stone Skin Amulets
ANTIBOT_RUNES = false
LEVEL_GAIN_FOR_KILL = 2 -- type nil to make it dependent on level (configurable: onKillPlayer)
MINIMUM_LEVEL = 100 -- when player will die then they will get this level // type nil for disable
MAXIMUM_LEVEL = 150 -- type nil to disable
MINIMUM_LEVEL_PRIVATE = 130 -- type nil for disable // TODO
MAXIMUM_LEVEL_PRIVATE = 200 -- type nil to disable // TODO
PLAYER_PROMOTION_LEVEL = 1
EXPERIENCE_BY_KILLING_PLAYERS = true
-- ANTI_RELOG_TIME = tonumber(getConfigValue("antiRelogTime")) -- deprecated as now
--[[ /CONFIG ]]

--[[
TEAM #1,
TEAM #2
]]
TEAMS_OUTFITS = {
{ colors = {52, 52, 52, 52}, addons = 3 }, -- array...
{ colors = 10, addons = 3 } -- or number (integer)
}

RUNES = {} --[[##do not touch it!##]]
-- {antibot, normal}
RUNES.UH = {2275, 2273}
RUNES.SD = {2263, 2268}
RUNES.EXPLO = {2312, 2313}
RUNES.HMM = {2314, 2311}
RUNES.GFB = {2307, 2304}
RUNES.PBOMB = {2270, 2286}
RUNES.EBOMB = {2282, 2262}
RUNES.FBOMB = {2306, 2305}
RUNES.MW = {2294, 2293}
GLOBAL_RUNE_TYPE = 2
if ANTIBOT_RUNES then
	GLOBAL_RUNE_TYPE = 1
end

ITEMS = {} --[[ ##do not touch it!## ]]
--for empty slot use nil or false
--[[sorcerer]] ITEMS[5] = {
	9778, --1 // head // yalahari mask
	2200, --2 // necakle // protection amulet
	2000, --3 // backpack // red backpack
	8890, --4 // armor // robe of the underworld
	8918, --5 // right hand // spellbook of dark mysteries
	8922, --6 // left hand // wand of voodoo
	7730, --7 // legs // blue legs
	6132, --8 // feet // soft boots
	2214, --9 // ring // ring of healing
	nil, --10 // ammo slot // EMPTY
	----
	--items to a backpack -- {id, inBackpack[, count/subtype]}
	----
	{RUNES.HMM[GLOBAL_RUNE_TYPE], false, 1}, --HMM
	{2274, false, 1}, --avalanche rune
	{RUNES.GFB[GLOBAL_RUNE_TYPE], false, 1}, --GFB
	{RUNES.PBOMB[GLOBAL_RUNE_TYPE], false, 1}, --poison bomb rune
	{RUNES.FBOMB[GLOBAL_RUNE_TYPE], false, 1}, --firebomb rune
	{RUNES.EBOMB[GLOBAL_RUNE_TYPE], false, 1}, --energy bomb rune
	{2261, false, 1}, --destroy field rune
	{RUNES.MW[GLOBAL_RUNE_TYPE], false, 1}, --magic wall rune
	{RUNES.UH[GLOBAL_RUNE_TYPE], false, 1}, --UH
	{RUNES.EXPLO[GLOBAL_RUNE_TYPE], false, 1}, --EXPLOSION
	{RUNES.SD[GLOBAL_RUNE_TYPE], false, 1}, --SD
	{7590, false} --GMP
}

--[[druid]] ITEMS[6] = {
	9778, --1 // head // yalahari mask
	2200, --2 // necakle // protection amulet
	2002, --3 // backpack // blue backpack
	8866, --4 // armor // serpent coat
	8918, --5 // right hand // spellbook of dark mysteries
	8910, --6 // left hand // underworld rod
	7730, --7 // legs // blue legs
	6132, --8 // feet // soft boots
	2214, --9 // ring // ring of healing
	nil, --10 // ammo slot // EMPTY
	----
	--items to a backpack -- {id, inBackpack[, count/subtype]}
	----
	{RUNES.HMM[GLOBAL_RUNE_TYPE], false, 1}, --HMM
	{2274, false, 1}, --avalanche rune
	{RUNES.GFB[GLOBAL_RUNE_TYPE], false, 1}, --GFB
	{RUNES.PBOMB[GLOBAL_RUNE_TYPE], false, 1}, --poison bomb rune
	{RUNES.FBOMB[GLOBAL_RUNE_TYPE], false, 1}, --firebomb rune
	{RUNES.EBOMB[GLOBAL_RUNE_TYPE], false, 1}, --energy bomb rune
	{2261, false, 1}, --destroy field rune
	{RUNES.MW[GLOBAL_RUNE_TYPE], false, 1}, --magic wall rune
	{RUNES.UH[GLOBAL_RUNE_TYPE], false, 1}, --UH
	{RUNES.EXPLO[GLOBAL_RUNE_TYPE], false, 1}, --EXPLOSION
	{RUNES.SD[GLOBAL_RUNE_TYPE], false, 1}, --SD
	{7590, false} --GMP
}

--[[paladin]] ITEMS[7] = {
	2493, --1 // head // demon helmet
	2200, --2 // necakle // protection amulet
	2003, --3 // backpack // grey backpack
	8888, --4 // armor // master archer's armor
	nil, --5 // right hand // EMPTY
	8850, --6 // left hand // chain bolter
	9777, --7 // legs // yalahari leg piece
	6132, --8 // feet // soft boots
	2214, --9 // ring // ring of healing
	6529, --10 // ammo slot // infernal bolts
	----
	--items to a backpack -- {id, inBackpack[, count/subtype]}
	----
	{RUNES.HMM[GLOBAL_RUNE_TYPE], false, 1}, --HMM
	{2274, false, 1}, --avalanche rune
	{RUNES.GFB[GLOBAL_RUNE_TYPE], false, 1}, --GFB
	{RUNES.PBOMB[GLOBAL_RUNE_TYPE], false, 1}, --poison bomb rune
	{RUNES.FBOMB[GLOBAL_RUNE_TYPE], false, 1}, --firebomb rune
	{RUNES.EBOMB[GLOBAL_RUNE_TYPE], false, 1}, --energy bomb rune
	{2261, false, 1}, --destroy field rune
	{RUNES.MW[GLOBAL_RUNE_TYPE], false, 1}, --magic wall rune
	{RUNES.UH[GLOBAL_RUNE_TYPE], false, 1}, --UH
	{RUNES.EXPLO[GLOBAL_RUNE_TYPE], false, 1}, --EXPLOSION
	{RUNES.SD[GLOBAL_RUNE_TYPE], false, 1}, --SD
	{8472, false} --GSP
}

--[[knight]] ITEMS[8] = {
	2493, --1 // head // demon helmet
	2200, --2 // necakle // protection amulet
	1999, --3 // backpack // yellow backpack
	9776, --4 // armor // yalahari armor
	6433, --5 // right hand // necromancer shield
	2431, --6 // left hand // stonecutter axe
	2470, --7 // legs // golden legs
	6132, --8 // feet // soft boots
	2214, --9 // ring // ring of healing
	nil, --10 // ammo slot // EMPTY
	----
	--items to a backpack -- {id, inBackpack[, count/subtype]}
	----
	{2274, false, 1}, --avalanche rune
	{RUNES.GFB[GLOBAL_RUNE_TYPE], false, 1}, --GFB
	{RUNES.PBOMB[GLOBAL_RUNE_TYPE], false, 1}, --poison bomb rune
	{RUNES.FBOMB[GLOBAL_RUNE_TYPE], false, 1}, --firebomb rune
	{RUNES.EBOMB[GLOBAL_RUNE_TYPE], false, 1}, --energy bomb rune
	{2261, false, 1}, --destroy field rune
	{RUNES.UH[GLOBAL_RUNE_TYPE], false, 1}, --UH
	{RUNES.EXPLO[GLOBAL_RUNE_TYPE], false, 1}, --EXPLOSION
	{7620, false}, --mana potion
	{7591, false} --GHP
}

ITEMS[1], ITEMS[2], ITEMS[3], ITEMS[4] = ITEMS[5], ITEMS[6], ITEMS[7], ITEMS[8]
ITEMS[0] = ITEMS[1] --prevents debugs
ITEMS[4294967295] = ITEMS[1] --prevents debugs

SKILLS = {}
--[[paladin]]
--[[
SKILLS[7] = {
	[SKILL_DISTANCE] = 92
}
]]
--[[knight]]
--[[
SKILLS[8] = {
	--[SKILL_CLUB] = 95,
	--[SKILL_SWORD] = 95,
	[SKILL_AXE] = 96
}
]]

STORAGE = {
	PLAYER = {
		TEAM_INFO = 40000
	},
	GLOBAL = {
		TEAMS = {40001, 40002},
		TEAMS_COUNT = {40011, 40012},
		AREA_ID = 40020
	}
}


---------------------------------------------------------------------
--[[ ##do not change anything below this line!## ]]------------------
---------------------------------------------------------------------

map = {	
	towns = {
		{"Fibula", {2, 3}},
		{"Venore", {5, 6}},
		{"Edron", {8, 9}},
		{"Thais", {11, 12}},
		{"Desert", {14, 15}}
	},
	
	get = function ()
		return getGlobalStorageValue(STORAGE.GLOBAL.AREA_ID)
	end,

	removeIssue = function ()
		if map.get() < 1 or map.get() > #map.towns then
			return setGlobalStorageValue(STORAGE.GLOBAL.AREA_ID, 1) and print("map.removeIssue: issue has been removed :: map is ".. map.towns[map.get()][1] .. " now")
		end
		return FALSE
	end,

	set = function ()
		map.removeIssue()
		return setGlobalStorageValue(STORAGE.GLOBAL.AREA_ID, (map.get() % #map.towns) + 1)
	end
}

team = {
	name = {
		"Alpha",
		"Bravo"
	},
	
	count = {
		get = function (teamId)
			return getGlobalStorageValue(STORAGE.GLOBAL.TEAMS_COUNT[teamId])
		end,

		add = function (teamId, count)
			return setGlobalStorageValue(STORAGE.GLOBAL.TEAMS_COUNT[teamId], team.count.get(teamId) + count)
		end
	},
	
	player = {
		get = function (cid)
			return ((getPlayerStorageValue(cid, STORAGE.PLAYER.TEAM_INFO) == STORAGE.GLOBAL.TEAMS[1]) and 1) or 2
		end,

		set = function (cid, id)
			return setPlayerStorageValue(cid, STORAGE.PLAYER.TEAM_INFO, id)
		end
	}
}

frag = {
	get = function (cid)
		return getPlayerSoul(cid)
	end,
	
	add = function (cid, count)
		return doPlayerAddSoul(cid, count)
	end
}

doPlayerSetTeam = {
	login = function (cid)
--		print("getSmallestTeam(): "..getSmallestTeam())
		if getPlayerAccess(cid) < 3 then
			if tonumber(MINIMUM_LEVEL) ~= nil then
				if isAccountPrivate(getPlayerAccountId(cid)) then
					doPlayerSetLevel(cid, MINIMUM_LEVEL_PRIVATE)
				else
					doPlayerSetLevel(cid, MINIMUM_LEVEL)
				end
			end
			setPlayerPromotionLevel(cid, PLAYER_PROMOTION_LEVEL)
			local playerTeam = getSmallestTeam()
			team.player.set(cid, STORAGE.GLOBAL.TEAMS[playerTeam])
--			print(type(TEAMS_OUTFITS[team].colors) .."\n".. type(TEAMS_OUTFITS[team].addons))
			doWarCreatureChangeOutfit(cid, TEAMS_OUTFITS[playerTeam].colors, TEAMS_OUTFITS[playerTeam].addons)
			doPlayerSetTown(cid, map.towns[map.get()][2][team.player.get(cid)])
			doTeleportThing(cid, getTownTemplePosition(getPlayerTown(cid)))
			team.count.add(playerTeam, 1)
			doPlayerAddSoul(cid, -getPlayerSoul(cid))
			doSendMagicEffect(getCreaturePosition(cid), 37)

			local vocSkills = SKILLS[getPlayerVocation(cid)]
			if vocSkills and vocSkills ~= nil then
				for skill = SKILL_FIST, SKILL_FISHING do
					doPlayerAddSkill(cid, skill, vocSkills[skill])
				end
			end
		end
--		print("Team 1 count: ".. team.count.get(1).. "\nTeam 2 count: ".. team.count.get(2))
		return TRUE
	end,

	logout = function (cid)
		if getPlayerAccess(cid) < 3 then
			local playerTeam = team.player.get(cid)
--			print("team.player.get(cid): ".. playerTeam)
			team.count.add(playerTeam, -1)
			team.player.set(cid, 0)
--			print("Team 1 count: "..team.count.get(1).."\nTeam 2 count: "..team.count.get(2))
		end
		return TRUE
	end

}

function doWarCreatureChangeOutfit(cid, colors, addons)
	local outfit = getCreatureOutfit(cid)
	if type(colors) == "number" then
		colors = {colors, colors, colors, colors}
	end
	outfit.lookHead, outfit.lookBody, outfit.lookLegs, outfit.lookFeet = unpack(colors)
	outfit.addons = addons or 3
	doCreatureChangeOutfit(cid, outfit)
	return true
end

function doChangeMap(clean, save)
	map.set()
	for _, pid in ipairs(getPlayersOnline()) do
		if getPlayerAccess(pid) < 3 then
			local temple = map.towns[map.get()][2][team.player.get(pid)]
			local oldPosition = getCreaturePosition(pid)
			doPlayerSetTown(pid, temple)
			doTeleportThing(pid, getTownTemplePosition(temple))
			doSendMagicEffect(getCreaturePosition(pid), 37)
			doSendMagicEffect(oldPosition, 2)
			doCreatureAddHealth(pid, getCreatureMaxHealth(pid))
			doCreatureAddMana(pid, (getCreatureMaxMana(pid) - getCreatureMana(pid)))
			doRemoveConditions(pid, FALSE)
		end
	end

	if clean then
		doCleanMap()
	end
	if save then
		doSaveServer(false)
	end

	doBroadcastMessage("Map has been changed. New area is ".. map.towns[map.get()][1] ..".", MESSAGE_EVENT_ORANGE)
	print(">> ".. os.date() .." :: Map has been changed. New area is ".. map.towns[map.get()][1] ..".")
    return TRUE
end

function doPlayerAddSkill(cid, skill, value)
	if skill and value then	
		--print("skill: ".. skill)
		--print("getPlayerSkillTries(cid, skill): ".. getPlayerSkillTries(cid, skill))
		doPlayerAddSkillTry(cid, skill, getPlayerRequiredSkillTries(cid, skill, value))
		--print("getPlayerSkillTries(cid, skill): ".. getPlayerSkillTries(cid, skill))
	end
	return true
end

function getSmallestTeam()
	return (team.count.get(1) > team.count.get(2) and 2) or 1
end

function isAccountPrivate(account)
	return ((account > 1) and true) or false
end

function doPlayerSetLevel(cid, level)
	return doPlayerAddExperience(cid, (getExperienceForLevel(level) - getPlayerExperience(cid)))
end

function doPlayerAddLevel(cid, amount)
	return doPlayerAddExperience(cid, getExperienceForLevel(getPlayerLevel(cid) + amount) - getPlayerExperience(cid))
end

function doResetTeams(teams)
	for team = 1, #teams do
		setGlobalStorageValue(teams[team], 0)
	end
	return true
end

function doInitializeWarServer()
		map.removeIssue()
		doResetTeams(STORAGE.GLOBAL.TEAMS_COUNT)
		return print(">>>>..::War has been initialized::..<<<<")
end

--[[
function onWarPrepareDeath(cid, deathList)
	for killer = 1, #deathList do
		if isPlayer(deathList[killer]) then
			if isPlayer(deathList[killer]) and deathList[killer] ~= cid then
				doPlayerAddSoul(deathList[killer], 1)
				doSendAnimatedText(getCreaturePosition(deathList[killer]), "FRAG!", 144, deathList[killer])
				if BAG_OF_SSA then
					doPlayerBuyItemContainer(deathList[killer], 1996, 2197, 1, 0, 5)
				end
				if EXPERIENCE_BY_KILLING_PLAYERS then
					local gainLevel = LEVEL_GAIN_FOR_KILL
					if  tonumber(gainLevel) == nil then
						gainLevel = math.floor(getPlayerLevel(cid) * 0.05) --here you can configure how many level will be added to killer(s)
					end
					local maximumLevel = MAXIMUM_LEVEL
					if isAccountPrivate(getPlayerAccountId(deathList[killer])) then
						maximumLevel = MAXIMUM_LEVEL_PRIVATE
					end
					if (maximumLevel == nil) or (getPlayerLevel(deathList[killer]) < maximumLevel) then
						doPlayerAddLevel(deathList[killer], gainLevel)
					end
				end
			end
		end

		if tonumber(MINIMUM_LEVEL) ~= nil then
			if isAccountPrivate(getPlayerAccountId(cid)) then
				doPlayerSetLevel(cid, MINIMUM_LEVEL_PRIVATE)
			else
				doPlayerSetLevel(cid, MINIMUM_LEVEL)
			end
		end

		doCreatureAddHealth(cid, getCreatureMaxHealth(cid), TRUE)
		doCreatureAddMana(cid, (getCreatureMaxMana(cid) - getCreatureMana(cid)))
		doPlayerAddSoul(cid, -getPlayerSoul(cid))
		doRemoveConditions(cid, FALSE)
		doSendMagicEffect(getCreaturePosition(cid), 2)
		doTeleportThing(cid, getTownTemplePosition(getPlayerTown(cid)))
		--doRemoveCreature(cid)	-- tepomporary
		--	return FALSE		-- tepomporary
		doSendMagicEffect(getCreaturePosition(cid), 37)
		return FALSE
	end
	return TRUE
end
]]

function onWarPrepareDeathByStatChange(cid, attacker, type, combat, value)
	if (type == STATSCHANGE_HEALTHLOSS) and (getCreatureHealth(cid) <= value) then
			if isPlayer(attacker) and attacker ~= cid then
				doPlayerAddSoul(attacker, 1)
				doSendAnimatedText(getCreaturePosition(attacker), "FRAG!", 144, attacker)
				if BAG_OF_SSA then
					doPlayerBuyItemContainer(attacker, 1996, 2197, 1, 0, 5)
				end
				if EXPERIENCE_BY_KILLING_PLAYERS then
					local gainLevel = LEVEL_GAIN_FOR_KILL
					if  tonumber(gainLevel) == nil then
						gainLevel = math.floor(getPlayerLevel(cid) * 0.05) --here you can configure how many level will be added to killer(s)
					end
					local maximumLevel = MAXIMUM_LEVEL
					if isAccountPrivate(getPlayerAccountId(attacker)) then
						maximumLevel = MAXIMUM_LEVEL_PRIVATE
					end
					if (maximumLevel == nil) or (getPlayerLevel(attacker) < maximumLevel) then
						doPlayerAddLevel(attacker, gainLevel)
					end
				end
		end

		if tonumber(MINIMUM_LEVEL) ~= nil then
			if isAccountPrivate(getPlayerAccountId(cid)) then
				doPlayerSetLevel(cid, MINIMUM_LEVEL_PRIVATE)
			else
				doPlayerSetLevel(cid, MINIMUM_LEVEL)
			end
		end

		doCreatureAddHealth(cid, getCreatureMaxHealth(cid), TRUE)
		doCreatureAddMana(cid, (getCreatureMaxMana(cid) - getCreatureMana(cid)))
		doPlayerAddSoul(cid, -getPlayerSoul(cid))
		doRemoveConditions(cid, FALSE)
		doSendMagicEffect(getCreaturePosition(cid), 2)
		doTeleportThing(cid, getTownTemplePosition(getPlayerTown(cid)))
		doSendMagicEffect(getCreaturePosition(cid), 37)
		return FALSE
	end
	return TRUE
end

talkactions = {
	getTeamsCount = function (cid)
		return doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_BLUE, "\n#Team ".. team.name[1] ..": ".. team.count.get(1) .."\n#Team ".. team.name[2] ..": ".. team.count.get(2))
	end,
	
	getMap = function (cid)
		return doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_BLUE, " The map is ".. map.towns[map.get()][1])
	end
}

function doPlayerShowFragsCount(cid, thing, position, lookDistance)
	if isPlayer(thing.uid) and getPlayerAccess(thing.uid) < 3 then
		doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_ORANGE, getCreatureName(thing.uid) .. " have got " .. getPlayerSoul(thing.uid) .. " frags.")
	end
	return TRUE
end

function doPlayerAddEquipment(cid)
	if getPlayerAccess(cid) < 3 then
		local vocItems = ITEMS[getPlayerVocation(cid)]
		for i = CONST_SLOT_FIRST, CONST_SLOT_LAST do
            local slotItem = getPlayerSlotItem(cid, i)
            if slotItem.itemid > 0 then
                doRemoveItem(slotItem.uid)
            end
            if vocItems[i] and vocItems[i] ~= nil and i ~= CONST_SLOT_BACKPACK then
				if i == CONST_SLOT_AMMO then
					doPlayerAddItem(cid, vocItems[i], 100)
				else
					doPlayerAddItem(cid, vocItems[i])
				end

            end
        end

		local backpack = doPlayerAddItem(cid, vocItems[CONST_SLOT_BACKPACK], 1)
		for b = 11, #vocItems do
			if vocItems[b] and vocItems[b] ~= nil then
				if vocItems[b][2] then
					vocItems[b][3] = vocItems[b][3] or 1
					doPlayerBuyItemContainer(cid, 2000, vocItems[b][1], 1, 0, vocItems[b][3])
				else
					doAddContainerItem(backpack, vocItems[b][1], vocItems[b][3])
				end
			end
		end
	end
 	return TRUE
end

function onPlayerAttack(cid, target)
	if cid ~= target and isPlayer(cid) and isPlayer(target) and team.player.get(cid) == team.player.get(target) then
		doPlayerSendCancel(cid, "You cannot attack your teammates.")
		return FALSE
	end
	return TRUE
end

